from __future__ import absolute_import
import logging
from forest.api import get_tool, Command

logger = logging.getLogger('forest.commands.RunScripts')

class RunScripts(Command):
    ''' Run scripts.

        These are defined in pre_scripts and post_scripts in the global config.

        They are a list of dictionaries. Each has the key "code" for inline code, or "file" to run a file.
    '''
    __register__ = 'commands.install.RunScripts'

    scripts = None

    def run(self, config):

        yum = config.get('_yum', None)

        for script in self.scripts:
            Command.SIGNAL_COMMAND_PROGRESS(self, level=logging.INFO, message='Executing installation scripts.')
            path = "<UNKNOWN>"
            if script.get('code'):
                logger.debug('Loading script from embedded.')
                string = script.get('code').strip()

            elif script.get('file'):
                logger.debug('Loading script from file.')

                path = script.get('file')

                path = config.get_defined_file(path)

                string = open(path,'r').read()

            execcode = compile(string, '', 'exec')

            chroot_path = config.get_install_root()

            with get_tool('system.chroot')(chroot_path):
                s = globals()
                s.update({'yum':yum})
                s.update({'config':config})
                l = locals()
                l.update({'yum':yum})
                l.update({'config':config})

                try:
                    exec execcode in s, l
                except Exception as err:
                    raise Exception('Script in {0} threw an exception {1}'.format(path, err))

class RunPreScripts(RunScripts):
    ''' Run scripts before package install.

        Scripts can be specified as files or included inline::

            pre_scripts:
                - file: <path to file>

                # OR

                - code: |

                  # python code
                  # can go here

                  import this
    '''
    __register__ = 'commands.install.RunPreScripts'

    requires_config = ['pre_scripts']

    def run(self, config):
        self.scripts = config.get('pre_scripts', [])
        super(RunPreScripts, self).run(config)

class RunPostScripts(RunScripts):
    ''' Run scripts after package install.

        Scripts can be specified as files or included inline::

            post_scripts:
                - file: <path to file>

                # OR

                - code: |

                  # python code
                  # can go here

                  import this
    '''
    __register__ = 'commands.install.RunPostScripts'

    requires_config = ['post_scripts']

    def run(self, config):
        self.scripts = config.get('post_scripts', [])
        super(RunPostScripts, self).run(config)
